'use strict';
const Utils = require('../../utils/Utils');
const BaseEntity = require("../../../libs/base/BaseEntity");
const moment = require('moment');

/**
 * 记录每一个生成的玩家的id以及对应的hall端口\游戏状态
 */
class Player {
    constructor() {
        this.pid = "";
        this.port = 0;
        this.nickName = "";
        this.game = 0;//当前所在场景/游戏。参考scenceId
        this.ip = "";//记录玩家ip
    }
    reset() {
        this.pid = "";
        this.hall = 0;
        this.nickName = "";
        this.game = 0;
        this.ip = "";
    }
}
/**
 * 记录每一个生成的玩家的id以及对应的hall端口\游戏状态
 */
class PlayerManager extends BaseEntity {
    constructor() {
        super();
        this.name = "";
        this.playerList = [];
        this.playerPools = [];
        this.pidIndex = 1;//用来生成系统的玩家id，保证唯一性。
        this.halls = [];//记录hall进程的port，
    }
    async init(name, serverConfig) {
        this.name = name;
        //获取hall端口列表，为hall负载均衡使用。
        const serviceConfig = serverConfig.find(p => p.name === "Hall");
        for (let j = 0; j < serviceConfig.number; j++) {
            this.halls.push(serviceConfig.port + j);
        }
        const pid = await Redis.get("pid");
        if (pid) {
            this.pidIndex = parseFloat(pid);
        } else {
            this.pidIndex = 1;
            Redis.set("pid", 1);
        }
    }
    async playerLogout(info) {
        let player;
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i].pid === info.pid) {
                player = this.playerList[i];
                break;
            }
        }
        const rt = await RPC.Hall.PlayerManager.logoutPlayer(player.port, player.pid);
        this.playerPools.push(this.playerList.splice(this.playerList.indexOf(player), 1));
    }

    /**
     * 老用户上线，只做记录的作用，不做任何处理
     */
    playerLogin(info) {
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i].pid === info.pid) {
                this.playerList[i].ip = info.ip;
                return this.playerList[i];
            }
        }
        let player = this.getPlayerFromPool();
        player.pid = info.pid;
        player.port = info.port || this.halls[parseFloat(info.pid) % this.halls.length];
        if (this.isDebug) {
            player.port = 3100;//调试阶段3100
        }
        player.nickName = info.nickName;
        player.game = info.game || 0;
        player.ip = info.ip;
        this.playerList.push(player);
        return player;
    }
    /**
     * 玩家是否已经在线
     */
    playerUni(pid) {
        for (let i = 0; i < this.playerList.length; i++) {
            if (this.playerList[i].pid === pid) {
                return this.playerList[i];
            }
        }
        return false;
    }
    /**
     * 新用户注册，生成pid和分配hall进行注册
     */
    async playerRegedit(info) {
        let player = await this.getNewPlayer();
        player.nickName = info.nickName;
        player.ip = info.ip;
        const playerInfo = await MySQL.regeditWXPlayer({
            pid: player.pid,
            openid: `${info.platform}_${info.openid}`,
            nickName: info.nickName,
            platform: info.platform,
            avatarUrl: info.avatarUrl || "",
            country: info.country || "",
            province: info.province || "",
            city: info.city || "",
            gender: info.gender + "" || "0",
            language: info.language || "zh_CN",
            createdAt: moment().format('YYYY-MM-DD HH:mm:ss'),
            lastLoginAt: moment().format('YYYY-MM-DD HH:mm:ss'),
        });

        this.playerList.push(player);
        return player;
    }
    async getNewPlayer() {
        this.pidIndex += 1;
        let adjustedTimestamp = Date.now().toString().slice(-3); // 获取时间戳后三位
        if (adjustedTimestamp[0] === '0') {
            adjustedTimestamp = Math.floor(Math.random() * 9) + 1 + adjustedTimestamp.slice(1);
        }
        const mysqlIndex = "01"; // 默认mysql索引为01
        const paddedPId = this.pidIndex.toString().padStart(9, '0'); // pid不足9位前面补0
        const newPId = `${adjustedTimestamp}${mysqlIndex}${paddedPId}`;
        let player = this.getPlayerFromPool();
        player.pid = `${newPId}${Utils.luhnChecksum(newPId)}`;
        player.port = this.halls[parseFloat(player.pid) % this.halls.length];
        if (this.isDebug) {
            player.port = 3100;//调试阶段3100
        }

        const rtn = await Redis.set("pid", this.pidIndex);
        if (rtn) {
            return player; // 将生成的玩家ID传入Utils.luhnChecksum
        } else {
            Logger.error(`${this.name}进程获取新的玩家id失败`);
        }
    }
    getPlayerFromPool() {
        if (this.playerPools.length > 0) {
            return this.playerPools.shift();
        } else {
            return new Player();
        }
    }
}
module.exports = PlayerManager;